package com.gxa.community.customer.service.classification.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gxa.community.core.pojo.bo.classification.GoodsInfoBo;
import com.gxa.community.core.pojo.dto.classification.ClassificationDTO;
import com.gxa.community.core.utils.R;
import com.gxa.community.customer.service.classification.ClassificationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@Transactional(rollbackFor = Throwable.class)
public class ClassificationServiceImpl implements ClassificationService {
    public static final String CLASSIFICATION_GOODS = "classification:";
    public static final String HOT_WORDS = "hotword:";
    public static final String GOODS_NAME = "goodsName:";
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private RestTemplate restTemplate;
    @Override
    public String queryAllClassificationContainGoodsInfo() {
        //先从redis中获取分类及商品信息：
        Object allClassification = redisTemplate.opsForValue().get(CLASSIFICATION_GOODS);
        if (StringUtils.isEmpty(allClassification)){
            //如果缓存中为空，则发起远程通信去后台获取
            String url = "http://localhost:8080/classification/queryallclassificationandAllgoodsinfo";


            String forObject = restTemplate.getForObject(url, String.class);
            redisTemplate.opsForValue().set(CLASSIFICATION_GOODS,forObject,24, TimeUnit.HOURS);
            return forObject;
        }
        return allClassification.toString();
    }

    @Override
    public String getAllHotWords() throws JsonProcessingException {
        //先从缓存中获取
        Object hotWord = redisTemplate.opsForValue().get(HOT_WORDS);
        if (StringUtils.isEmpty(hotWord)){
            //缓存中不存在，发起远程通信，向后台获取
            String url = "http://localhost:8080/content/remotegetallhotwords";
            R r = restTemplate.getForObject(url, R.class, (Object) null);
            ObjectMapper objectMapper = new ObjectMapper();
            String result = objectMapper.writeValueAsString(r);
            redisTemplate.opsForValue().set(HOT_WORDS,result,24,TimeUnit.HOURS);
            return result;
        }
        return hotWord.toString();
    }

    @Override
    public String searchGoods(String name) throws JsonProcessingException {
        //直接从redis中查找
        String goodsInfos = (String) redisTemplate.opsForValue().get(GOODS_NAME+name);
        if (StringUtils.isEmpty(goodsInfos)){
            Object classificationGoods = redisTemplate.opsForValue().get(CLASSIFICATION_GOODS);
            String classificationGoods1 = classificationGoods.toString();
            if (StringUtils.isEmpty(classificationGoods1)){
                classificationGoods1 = this.queryAllClassificationContainGoodsInfo();
            }
            //把redis中的缓存转换成对象
            ObjectMapper objectMapper = new ObjectMapper();
            R r = objectMapper.readValue(classificationGoods1, R.class);
            List<ClassificationDTO> classificationDTOS1 = (List<ClassificationDTO>) r.get("allClassification");
            //当对象中含有对象  需使用下列步骤进行反序列化
            List<ClassificationDTO> classificationDTOS = objectMapper.convertValue(classificationDTOS1, new TypeReference<List<ClassificationDTO>>() {
                @Override
                public Type getType() {
                    return super.getType();
                }
            });
            List<GoodsInfoBo> goodsInfoBoList1 = new ArrayList<>();
            for (ClassificationDTO classificationDTO : classificationDTOS) {
                List<GoodsInfoBo> goodsInfoBoList = classificationDTO.getGoodsInfoBoList();
                for (GoodsInfoBo goodsInfoBo : goodsInfoBoList) {
                    if (goodsInfoBo.getName().contains(name)){
                        goodsInfoBoList1.add(goodsInfoBo);
                    }
                }
            }
            if (CollectionUtils.isEmpty(goodsInfoBoList1)){
                return objectMapper.writeValueAsString(R.error(600,"很抱歉，未查询到你欲寻找的商品，请重新输入！"));
            }
            goodsInfos = objectMapper.writeValueAsString(R.ok("查询成功！").put("data", goodsInfoBoList1));
            redisTemplate.opsForValue().set(GOODS_NAME+name,goodsInfos,2,TimeUnit.HOURS);
        }
        return goodsInfos;
    }
}
